//
// Created by 16586 on 2024/8/14.
//

#include "OboeRender.h"
OboeRender::OboeRender(){

};

void OboeRender::StartRender() {

    result = builder.openStream(mStream);
    mStream->requestStart();
}

void OboeRender::ClearAudioCache() {


    LOGCATE("result1   11113423232411134334");
    while (GetAudioFrameQueueSize()<MAX_QUEUE_BUFFER_SIZE&&!m_Exit){
        std::unique_lock<std::mutex> lock(m_Mutex);
        LOGCATE("result1  wait_for m_BufferQueue");
        m_Cond.wait_for(lock, std::chrono::milliseconds(10));
        lock.unlock();
    }

    result = mStream->requestStart();
}




oboe::DataCallbackResult OboeRender::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {

    LOGCATE("RenderAudioFrame OboeRender %d",numFrames);
    LOGCATE("result1   11113423232411134334   %d",audioStream->getFormat());
    while (GetAudioFrameQueueSize() < MAX_QUEUE_BUFFER_SIZE && !m_Exit) {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_Cond.wait_for(lock, std::chrono::milliseconds(10));
    }
    std::unique_lock<std::mutex> lock(m_Mutex);
    AudioFrame *audioFrame = m_AudioFrameQueue.front();
    uint16_t *floatData = (uint16_t *) audioData;
    if (audioFrame!= nullptr){
        memcpy(floatData, reinterpret_cast<const uint16_t *const>(audioFrame->data),
               sizeof(float) * numFrames * channelCount);
        return oboe::DataCallbackResult::Continue;
    }
    return oboe::DataCallbackResult::Stop;
}


void OboeRender::UnInit() {
    result = mStream->stop();
//    mStream->getFormat()
}

void OboeRender::RenderAudioFrame(uint8_t *pData, int dataSize) {


//    mStream->getBufferCapacityInFrames();
    LOGCATE("RenderAudioFrame1 %d %d",dataSize,strlen(reinterpret_cast<const char *const>(pData)));
    if (pData!= nullptr&&dataSize>0){
        LOGCATE("RenderAudioFrame1 %d %d",dataSize,strlen(reinterpret_cast<const char *const>(pData)));

        while(GetAudioFrameQueueSize()>=MAX_QUEUE_BUFFER_SIZE){
            this_thread::sleep_for(chrono::milliseconds(10));
        }
        unique_lock<mutex> lock(m_Mutex);
        AudioFrame *audioFrame=new AudioFrame(pData,dataSize);
        m_AudioFrameQueue.push(audioFrame);
        m_Cond.notify_all();
        lock.unlock();
    }
}

int OboeRender::GetAudioFrameQueueSize() {
    std::unique_lock<std::mutex> lock(m_Mutex);
    return m_AudioFrameQueue.size();
}


void OboeRender::CreateSLWaitingThread(OboeRender *OboeRender) {
    OboeRender->StartRender();


}
void OboeRender::Init() {
    builder=oboe::AudioStreamBuilder();
    result = builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
            ->setSharingMode(oboe::SharingMode::Exclusive)
            ->setChannelCount(channelCount)
            ->setDirection(oboe::Direction::Output)
            ->setSampleRate(kSampleRate)
            ->setFormat(oboe::AudioFormat::I16)
            ->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium)
            ->setFormatConversionAllowed(true)
            ->setDataCallback(this)
            ->setDeviceId(0)
            ->openStream(mStream);

    if (result != oboe::Result::OK) return;

    StartRender();
    // (int32_t) result;

    if (result != oboe::Result::OK) return; // (int32_t) result;

    m_thread = new thread(CreateSLWaitingThread,this);



}


